//!三.封装CRUD操作（第一步在Entity）

using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using TM.Api.Entity;

namespace TM.Api.Repository
{
    /// <summary>
    /// 定义一个接口，用于实体类型的CRUD操作
    /// </summary>
    /// <typeparam name="T">泛型，可以是任意一个实体类型(例如Users表)</typeparam>
    public interface IRepository<T> where T : BaseEntity
        //! 这里的T是以下所有T的指向
    {


        /// <summary>
        /// IQueryable:Linq自带的接口，可执行LINQ操作。
        /// </summary>
        /// <value></value>
        IQueryable<T> Table { get; }



        /// <summary>
        /// 根据提供的id，查询对应的T实例
        /// </summary>
        /// <param name="id">提供的id，这里可能是int、long、guid等常见的主键类型</param>
        /// <returns></returns>
        T GetById(object id);



        /// <summary>
        /// 根据提供的实体对象，插入到数据库
        /// </summary>
        /// <param name="entity">实体对象</param>
        void Insert(T entity);



        /// <summary>
        /// 根据提供的实体对象，异步插入到数据库
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns></returns>
        Task InsertAsync(T entity);
        //? Task:多线程任务控制(异步)



        /// <summary>
        /// 根据提供的实体对象集合，批量插入到数据库
        /// </summary>
        /// <param name="entities">实体对象集合</param>
        void InsertBulk(IEnumerable<T> entities);
        //?  IEnumerable:公开枚举数，该枚举数支持在指定类型的集合上进行简单迭代。



        /// <summary>
        /// 根据提供的实体对象集合，异步批量插入到数据库
        /// </summary>
        /// <param name="entities">实体对象集合</param>
        /// <returns></returns>
        Task InsertBulkAsync(IEnumerable<T> entities);



        /// <summary>
        /// 根据提供的主键id，删除数据库中对应的记录
        /// </summary>
        /// <param name="id">提供的id，这里可能是int、long、guid等常见的主键类型</param>
        void Delete(object id);


        /// <summary>
        /// 根据提供的主键id集合，删除数据库中对应的记录
        /// </summary>
        /// <param name="ids">id集合</param>
        void DeleteBulk(IEnumerable<object> ids);



        /// <summary>
        /// 根据提供的实体对象，更新实体到数据库
        /// </summary>
        /// <param name="entity">实体对象</param>
        void Update(T entity);



        /// <summary>
        ///  根据提供的实体对象集合，更新实体到数据库
        /// </summary>
        /// <param name="entities">实体对象集合</param>
        void UpdateBulk(IEnumerable<T> entities);
    }
}

//! 第四步去 EfRepository。